
#ifndef __CCONF_H
#define __CCONF_H

#include <stdio.h>
#include <stdlib.h>

#define CCONF_TABLE_SIZE 256
#define CCONF_MAX_ENTRY_LEN 64
#define CCONF_NAMESPACE_SEP ':'

#define CCONF_SOCKET_PATH "/tmp/cconf_ipc"

typedef struct cconf_s cconf_t;

typedef void (*cconf_changed_fcn_t)(cconf_t * c, char * path, void * arg);

typedef enum {
    CCONF_STR_NODUP=0,
    CCONF_STR_DUP
} cconf_str_behavior_t;

typedef enum {
	CCONF_ADD_MODE_UPDATE,
	CCONF_ADD_MODE_UNIQUE,
} cconf_add_mode_t;

typedef enum {
	CCONF_ACCESS_GET,
	CCONF_ACCESS_CLEAR,
} cconf_access_type_t;

typedef enum {
	CCONF_FAIL_ON_INSANE,
	CCONF_WARN_ON_INSANE,
} cconf_sanity_t;

int cconf_check_errors(cconf_t * cconf);
char * cconf_get_errors(cconf_t * c);

int cconf_set_value(cconf_t * c, char * path, char * value);

char * cconf_get_value_str(cconf_t * c, char * format, ...);
char * cconf_get_value_strc(cconf_t * c, char * format, ...);

int cconf_get_value_int(cconf_t * c, char * format, ...);
float cconf_get_value_float(cconf_t * c, char * format, ...);

int cconf_add_entry_usr(
	cconf_t * c, char * path, char * def, char * docstring, char * envspec,
	int (*validate_fcn)(char ** err, char * value, void * arg),
	void * arg, char * v_docstring
);

int cconf_add_entry_intrange(
	cconf_t * c, char * path, char * def, 
	char * docstring, char * envspec, int lo, int hi
);
	
int cconf_add_entry_int(
	cconf_t * c, char * path, char * def, char * docstring, char * envspec);
	
int cconf_add_entry_doublerange(
	cconf_t * c, char * path, char * def, 
	char * docstring, char * envspec, double lo, double hi
);
	
int cconf_add_entry_double(
	cconf_t * c, char * path, char * def, char * docstring, char * envspec);
	
int cconf_add_entry_strlist(
	cconf_t * c, char * path, char * def, 
	char * docstring, char * envspec, char * list);
	
int cconf_add_entry_str(
cconf_t * c, char * path, char * def, char * docstring, char *envspec);

int cconf_add_entry_specifier(
	cconf_t * c, char * path, char * spec, char * def);
	
int cconf_add_entries(cconf_t * c, ...);

int cconf_read(cconf_t * c, char * config_file);

char * cconf_dump(cconf_t * c, char * rs, char * dl);
char * cconf_document(cconf_t * c);
char * cconf_document_entry(cconf_t * c, char * entry_name);
int cconf_document_file(cconf_t * cfg, FILE * fp, char * entry_name);

void cconf_print(cconf_t *c);

cconf_t * cconf_create(char * name, cconf_changed_fcn_t cb, void * cb_arg);

int cconf_start_io_thread(cconf_t * c, char * name);

int cconf_free(cconf_t * c);

int cconf_optparse(cconf_t * c, int argc, char ** argv);

#endif
